﻿using GamFi.API.Application.DefaultSettings;
using GamFi.API.Application.Exceptions;
using GamFi.API.Application.Interfaces;
using GamFi.API.Application.Resources;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;

namespace GamFi.API.Application.Features.Queries.Token.PostAddToken;

public class PostAddTokenCommandHandler(
    IDbContext dbContext,
    IUserContext userContext,
    UserManager<Domain.Entities.User> userManager,
    IStringLocalizer<ExceptionMessages> localizer)
    : IRequestHandler<PostAddTokenCommand, Unit>
{
    public async Task<Unit> Handle(PostAddTokenCommand request, CancellationToken cancellationToken)
    {
        if (request is null)
            throw new RequestException(localizer[nameof(RequestException.RequestIsEmpty)]);

        if (userContext.CurrentUserId is null)
            throw new UserException(localizer[nameof(UserException.PermissionDenied)]);

        var user = await dbContext.Users
            .FirstOrDefaultAsync(u => u.Id == userContext.CurrentUserId, cancellationToken: cancellationToken);

        if (user is null)
            throw new UserException(localizer[nameof(UserException.UserByIdNotFound)]);

        var newToken = new Domain.Entities.Token
        {
            ChainId = request.ChainId,
            TokenSymbol = request.TokenSymbol,
            CreatedBy = user.UserInfoId,
            CreatedDate = DateTime.UtcNow,
            Name = request.Name.ToUpper(),
            TokenPrice = request.TokenPrice,
            TargetedRaise = request.TargetedRaise,
            TotalRaise = 0,
            TokenSummary = request.TokenSummary,
            ImageId = request.ImageId != null ? Guid.Parse(request.ImageId) : null
        };

        await dbContext.Tokens.AddAsync(newToken, cancellationToken);

        var creator = await userManager.FindByIdAsync(userContext.CurrentUserId.Value.ToString());

        if (creator == null)
            throw new UserException(localizer[nameof(UserException.UserByIdNotFound)]);

        await userManager.AddToRoleAsync(creator, BaseRoles.CreatorRoleName.ToUpper());

        await dbContext.SaveChangesAsync(cancellationToken);

        return Unit.Value;
    }
}